﻿using System;
using System.Text;
using System.Media;
using System.Management;
using System.Diagnostics;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace CoreShop.Library
{
    /// <summary>
    /// 电脑信息操作类
    /// </summary>
    public class ComputerTool
    {
        [DllImport("user32 ")]
        static extern bool LockWorkStation();//调用windows的系统锁定

        /// <summary>
        /// 需要初始化才能使用
        /// </summary>
        static PerformanceCounter pcCpuLoad;   //CPU计数器

        /// <summary>
        /// 清理系统内存函数
        /// </summary>
        /// <param name="hwProc"></param>
        /// <returns></returns>
        [DllImport("psapi.dll")]
        private static extern int EmptyWorkingSet(IntPtr hwProc);

        static ComputerTool()
        {
            //Task.Factory.StartNew(() =>
            //{
            //    //初始化CPU计数器 
            //    pcCpuLoad = new PerformanceCounter();
            //    pcCpuLoad.NextValue();
            //});
        }

        /// <summary>
        /// 获取内存最大容量
        /// 字节
        /// </summary>
        /// <returns></returns>
        public static Int64 GetMemory()
        {
            using (ManagementObjectSearcher searcher =
                new ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem"))
            {
                foreach (ManagementObject obj in searcher.Get())
                {
                    return Convert.ToInt64(obj["TotalPhysicalMemory"]);
                }
            }

            return 0;
        }

        /// <summary>
        /// 获取可用内存
        /// MB
        /// </summary>
        /// <returns></returns>
        public static long GetAvailableMemory()
        {
            using (PerformanceCounter ramCounter = new PerformanceCounter("Memory", "Available MBytes"))
            {
                return ramCounter.NextSample().RawValue;
            }
        }

        /// <summary>
        /// 获取已用内存
        /// 比例
        /// </summary>
        /// <returns></returns>
        public static float GetCommittedMemory()
        {
            using (PerformanceCounter ramCounter = new PerformanceCounter("Memory", "% Committed Bytes In Use"))
            {
                return ramCounter.NextValue();
            }
        }

        /// <summary>
        /// 得到cpu使用率
        /// </summary>
        /// <returns></returns>
        public static float GetCpu()
        {
            return pcCpuLoad.NextValue();
        }

        /// <summary>
        /// 释放所有进程内存
        /// 建议线程异步
        /// </summary>
        /// <param name="prossname">进程名称，为空则清理所有</param>
        public static void ClearAllMemory(string prossname = "")
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Process[] processes;

            if (!string.IsNullOrEmpty(prossname))
            {
                processes = Process.GetProcessesByName(prossname);
            }
            else
            {
                processes = Process.GetProcesses();
            }

            foreach (Process process in processes)
            {
                //对于系统进程会拒绝访问，导致出错，此处对异常不进行处理。
                try
                {
                    EmptyWorkingSet(process.Handle);
                }
                catch { }
            }
        }

        /// <summary>
        /// 锁屏
        /// </summary>
        public static void LockScreen()
        {
            //LockWorkStation();
        }

        /// <summary>
        /// 获取当前输入法
        /// </summary>
        /// <returns></returns>
        public static string GetLanguageType()
        {
            InputLanguageCollection currentInputLanguage = InputLanguage.InstalledInputLanguages;

            foreach (InputLanguage inputLanguage in currentInputLanguage)
            {
                Console.WriteLine(inputLanguage.Handle);
            }

            return "";
        }

        /// <summary>
        /// 切换输入法
        /// </summary>
        /// <param name="cultureType">语言项，如zh-CN，en-US</param>
        public static void SwitchToLanguageMode(string cultureType)
        {
            InputLanguage.CurrentInputLanguage = InputLanguage.FromCulture(System.Globalization.CultureInfo.GetCultureInfo(cultureType));
        }

        /// <summary>
        /// 获取硬件标识符
        /// </summary>
        /// <param name="wmiClass"></param>
        /// <param name="wmiProperty"></param>
        /// <returns></returns>
        private static string GetComputerIdentifier(string wmiClass, string wmiProperty)
        {
            string result = "";
            System.Management.ManagementObjectCollection moc = new System.Management.ManagementClass(wmiClass).GetInstances();

            foreach (System.Management.ManagementObject mo in moc)
            {
                //Only get the first one
                if (result == "")
                {
                    if (mo[wmiProperty] != null)
                    {
                        result = mo[wmiProperty].ToString();
                    }

                    break;
                }
            }

            return result;
        }

        /// <summary>
        /// 获取第一个硬盘的id
        /// </summary>
        /// <returns></returns>
        public static String GetComputerDiskID()
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");

            foreach (ManagementObject mo in searcher.Get())
            {
                if (mo["SerialNumber"] != null)
                {
                    return mo["SerialNumber"].ToString().Trim();
                }
            }

            return string.Empty;
        }

        /// <summary>
        /// 取CPU编号
        /// </summary>
        /// <returns></returns>
        public static string GetComputerCpuID()
        {
            ManagementClass mc = new ManagementClass("Win32_Processor");
            ManagementObjectCollection moc = mc.GetInstances();

            foreach (ManagementObject mo in moc)
            {
                if (mo.Properties["ProcessorId"] != null && mo.Properties["ProcessorId"].Value != null)
                {
                    return mo.Properties["ProcessorId"].Value.ToString();
                }
            }

            return string.Empty;
        }

        /// <summary>
        /// 执行内部命令（cmd.exe 中的命令）
        /// </summary>
        /// <param name="cmdline">命令行</param>
        /// <param back="back">是否需要在后台执行</param>
        /// <returns>执行结果</returns>
        public static string ExecuteInCmd(string cmdline)
        {
            using (Process process = new Process())
            {
                process.StartInfo.FileName = "cmd.exe";
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardInput = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError = true;
                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.StandardOutputEncoding = Encoding.UTF8;

                process.Start();
                process.StandardInput.AutoFlush = true;
                process.StandardInput.WriteLine(cmdline + " &exit");

                //获取cmd窗口的输出信息
                string output = process.StandardOutput.ReadToEnd();

                process.WaitForExit(10000);

                return output;
            }
        }

        /// <summary>
        /// 后台持续执行
        /// </summary>
        /// <param name="cmdline"></param>
        public static void ExecuteInCmdForBack(string cmdline)
        {
            Process process = new Process();
            ProcessStartInfo processStartInfo = new ProcessStartInfo();

            processStartInfo.FileName = cmdline;
            processStartInfo.CreateNoWindow = true;
            processStartInfo.UseShellExecute = false;
            //processStartInfo.RedirectStandardInput = true;
            //processStartInfo.RedirectStandardOutput = true; // 重定向输出
            //processStartInfo.RedirectStandardError = true;
            process.StartInfo = processStartInfo;

            process.Start();
            //process.StandardInput.WriteLine(cmdline);
            //process.StandardInput.Flush();
        }

        /// <summary>
        /// 发出成功的提示声音
        /// </summary>
        public static void Sound4Success()
        {
            SystemSounds.Exclamation.Play();
        }

        /// <summary>
        /// 发出失败的提示声音
        /// </summary>
        public static void Sound4Error()
        {
            SystemSounds.Beep.Play();
        }

        /// <summary>
        /// 发出提示声音
        /// </summary>
        public static void Sound4Show()
        {
            //SystemSounds.Hand.Play();
            SystemSounds.Asterisk.Play();
        }

        /// <summary>
        /// 获取本地的打印机名称
        /// </summary>
        /// <returns></returns>
        public static List<string> GetPrintDeviceName()
        {
            List<string> output = new List<string>();
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(" select * from win32_printer ");

            ManagementObjectCollection managementBaseObjects = searcher.Get();

            foreach (ManagementObject managementObject in managementBaseObjects)
            {
                output.Add(managementObject["Name"]?.ToString());
            }

            return output;
        }
    }
}
